// 封装、继承、多态
// class Person{
//     //私有属性前面要加# 私有属性不可以直接省略
//
//     #name;
//     #age=20
//     static flag= 'xxx'
//     constructor(name,age){  //构造函数是没有返回值的！！
//         this.#name=name;  //this是指创建出的对象
//         this.#age=age;
//     }
//
//     get Age(){
//         console.log('get方法被调用了!');
//         return this.#age
//     }
//     set Age(age){
//         console.log('set方法被调用了!');
//         if (age<0||age>150){
//             this.#age=20;
//         }else {
//             this.#age=age
//         }
//
//     }
//
// }
//
// let person1=new Person('luojinsheng',20);
// console.log(person1);
// person1.Age = 200;
// console.log(person1.Age);
// console.log(person1);



// class Person {
//     //私有属性前面要加# 私有属性不可以直接省略
//     #name;
//     #age;
//     #sex;
//
//     constructor(name, age, sex) {  //构造函数是没有返回值的！！
//         this.#name = name;  //this是指创建出的对象
//         this.#age = age;
//         this.#sex = sex;
//     }
//
//     get name() {
//         console.log('get方法被调用了!');
//         return this.#name
//     }
//     //...此处省略get()和set()
// }
// let person1 = new Person('luojinsheng', 20, '男');
// console.log(person1);
// console.log(person1.name);
//
// class Teacher{
//         #name;
//     #age;
//     #sex;
//
//     constructor(name, age, sex) {  //构造函数是没有返回值的！！
//         this.#name = name;  //this是指创建出的对象
//         this.#age = age;
//         this.#sex = sex;
//     }
//
//     get name() {
//         console.log('get方法被调用了!');
//         return this.#name
//     }
//     //...此处省略get()和set()
//
//     teach(){
//         console.log('我能teach');
//     }
// }
// let teacher1 = new Teacher('luodada', 21, '男');
// console.log(teacher1);
// console.log(teacher1.name);
// teacher1.teach();
//
// class Students{
//         #name;
//     #age;
//     #sex;
//
//     constructor(name, age, sex) {  //构造函数是没有返回值的！！
//         this.#name = name;  //this是指创建出的对象
//         this.#age = age;
//         this.#sex = sex;
//     }
//
//     get name() {
//         console.log('get方法被调用了!');
//         return this.#name
//     }
//     //...此处省略get()和set()
//
//     study(){
//         console.log('我能study');
//     }
// }
// let student1 = new Students('yangxiaoxiao', 20, '女');
// console.log(student1);
// console.log(student1.name);
// student1.study();


//继承 extends  class Teacher extends Person
// class Person {
//     //私有属性前面要加# 私有属性不可以直接省略
//     #name;
//     #age;
//     #sex;
//
//     constructor(name, age, sex) {  //构造函数是没有返回值的！！
//         this.#name = name;  //this是指创建出的对象
//         this.#age = age;
//         this.#sex = sex;
//     }
//
//     get name() {
//         // console.log('get方法被调用了!');
//         return this.#name
//     }
//     //...此处省略get()和set()
//
//     sayHello(){
//         console.log('hello!person');
//     }
// }
// let person1 = new Person('luojinsheng', 20, '男');
// console.log(person1.name);
// person1.sayHello()
//
// class Teacher extends Person {
//     teach(){
//         console.log('我能teach');
//     }
//
//     //子类方法重写(覆盖)
//     sayHello(){
//         console.log('hello!teacher');
//     }
//
//     toString(){
//         return `${this.name}`  //不需要用#name 因为有get()
//     }
// }
// let teacher1 = new Teacher('luodada', 21, '男');
// console.log(teacher1.name);
// teacher1.teach();
// teacher1.sayHello()
// console.log(teacher1.toString())


//super重写
// class Person {
//     //私有属性前面要加# 私有属性不可以直接省略
//     #name;
//     #age;
//     #sex;
//
//     constructor(name, age, sex) {  //构造函数是没有返回值的！！总计一下：私有属性的#name一般只出现在constructor() get() set()这三个方法里面 其他地方大部分都是直接用name
//         this.#name = name;  //this是指创建出的对象
//         this.#age = age;
//         this.#sex = sex;
//     }
//
//     get name() {
//         // console.log('get方法被调用了!');
//         return this.#name
//     }
//     set name(value) {
//         console.log('set方法被调用了!');
//         this.#name = value
//     }
//     //...此处省略get()和set()
//
//     sayHello(){
//         console.log('hello!person');
//     }
// }
// let person1 = new Person('luojinsheng', 20, '男');
// console.log(person1.name);
// person1.sayHello()
//
// class Teacher extends Person {
//     constructor(name, age, sex) {  //如果重写的constructor()没有带参数 则无法在后面实例化的时候有属性
//         super(name, age, sex);  //访问父类的构造函数 第一行必须这样写 否则无法创建父类对象
//         this.name = name+'xxx';  //this是指创建出的对象
//     }
//     teach(){
//         console.log('我能teach');
//         this.sayHello()
//         super.sayHello()  //super调用父类的方法
//     }
//
//     //子类方法重写(覆盖)
//     sayHello(){
//         console.log('hello!teacher');
//     }
//
//     toString(){
//         return `${this.name}`  //不需要用#name 因为有get()
//     }
// }
// let teacher1 = new Teacher('luodada', 21, '男');
// console.log(teacher1.name);  //如果重写的constructor()没有带参数 则无法在后面实例化的时候有属性 这个时候结果就是undefined
// teacher1.teach();
// teacher1.sayHello()
// console.log(teacher1.toString())



//多态：是指同一个方法 由于对象不同会有不同的行为
class Demo {
    sayHello() {
        console.log('hello!luodada');
    }
}

class Test extends Demo {
    sayHello() {
        console.log('hello!yangxiaoxiao');
    }
}

function abc(obj) {
    obj.sayHello()
}

let demo = new Demo();
let test = new Test();
abc(demo);
abc(test);


